/**
 * src/utils/notificationUtils.ts
 * ------------------------------------
 * 通知系统工具
 * 1. NotificationUtils：通知创建、发送、管理、清理等核心功能
 * 2. Notification：通知对象接口，包含标题、内容、类型、优先级等
 * 3. NotificationType：通知类型枚举（订单相关、系统消息等）
 * 4. NotificationPriority：通知优先级（低、普通、高）
 * 5. 支持微信订阅消息、本地通知、通知状态管理
 * 所有通知相关的业务逻辑都通过此工具类处理
 * 创建日期：2025-08-06
 */
import Taro from '@tarojs/taro'
import { Order, User } from '../types'
import { CloudDataManager } from './cloud'
import { errorUtils, ErrorType } from './errorHandler'
import { formatDateTime } from './index'

// 通知类型
export type NotificationType = 
  | 'order_created'
  | 'order_confirmed'
  | 'order_completed'
  | 'order_cancelled'
  | 'chef_assigned'
  | 'payment_received'
  | 'system_message';

// 通知优先级
export enum NotificationPriority {
  LOW = 'low',
  NORMAL = 'normal',
  HIGH = 'high'
}

// 通知状态
export type NotificationStatus = 'pending' | 'sent' | 'failed' | 'read';

// 通知对象
export interface Notification {
  id?: string;
  userId: string;
  title: string;
  content: string;
  type: NotificationType;
  priority: NotificationPriority;
  status: NotificationStatus;
  referenceId?: string; // 关联ID，如订单ID
  createdAt: Date;
  sentAt?: Date;
  readAt?: Date;
  data?: any; // 额外数据
}

// 订阅消息模板
interface SubscriptionTemplate {
  templateId: string;
  title: string;
  content: string;
  page: string;
}

// 通知系统工具类
export class NotificationUtils {
  // 订阅消息模板ID映射
  private static readonly TEMPLATES: Record<NotificationType, SubscriptionTemplate> = {
    order_created: {
      templateId: 'template_id_1', // 替换为实际模板ID
      title: '订单创建通知',
      content: '您的订单已创建',
      page: 'pages/order/detail'
    },
    order_confirmed: {
      templateId: 'template_id_2',
      title: '订单确认通知',
      content: '您的订单已确认',
      page: 'pages/order/detail'
    },
    order_completed: {
      templateId: 'template_id_3',
      title: '订单完成通知',
      content: '您的订单已完成',
      page: 'pages/order/detail'
    },
    order_cancelled: {
      templateId: 'template_id_4',
      title: '订单取消通知',
      content: '您的订单已取消',
      page: 'pages/order/detail'
    },
    chef_assigned: {
      templateId: 'template_id_5',
      title: '厨师分配通知',
      content: '您的订单已分配厨师',
      page: 'pages/order/detail'
    },
    payment_received: {
      templateId: 'template_id_6',
      title: '支付成功通知',
      content: '您的支付已成功',
      page: 'pages/order/detail'
    },
    system_message: {
      templateId: 'template_id_7',
      title: '系统通知',
      content: '系统通知',
      page: 'pages/notification/index'
    }
  };

  // 重试次数
  private static readonly MAX_RETRIES = 3;
  // 重试间隔（毫秒）
  private static readonly RETRY_INTERVAL = 5000;

  /**
   * 创建通知
   * @param notification 通知信息
   * @returns Promise<string> 通知ID
   */
  static async createNotification(notification: Omit<Notification, 'id'>): Promise<string> {
    try {
      // 保存通知到数据库
      const notificationId = await CloudDataManager.addData('notifications', notification)
      
      // 如果是高优先级通知，立即发送
      if (notification.priority === NotificationPriority.HIGH) {
        await this.sendNotification(notificationId)
      }
      
      return notificationId
    } catch (error) {
      errorUtils.handleError(error, ErrorType.DATABASE, {
        showToast: false,
        data: { operation: 'createNotification' }
      })
      throw error
    }
  }

  /**
   * 发送通知
   * @param notificationId 通知ID
   * @returns Promise<boolean>
   */
  static async sendNotification(notificationId: string): Promise<boolean> {
    try {
      // 获取通知信息
      const notification = await CloudDataManager.getData('notifications', notificationId) as Notification
      
      if (!notification) {
        throw new Error('通知不存在')
      }
      
      if (notification.status === 'sent') {
        return true // 已发送过
      }
      
      // 发送通知
      let success = false
      
      // 根据通知类型选择发送方式
      switch (notification.type) {
        case 'order_created':
        case 'order_confirmed':
        case 'order_completed':
        case 'order_cancelled':
        case 'chef_assigned':
        case 'payment_received':
          // 尝试发送订阅消息
          success = await this.sendSubscriptionMessage(notification)
          break
          
        case 'system_message':
        default:
          // 系统通知仅保存到数据库
          success = true
          break
      }
      
      // 更新通知状态
      await CloudDataManager.updateData('notifications', notificationId, {
        status: success ? 'sent' : 'failed',
        sentAt: success ? new Date() : undefined
      })
      
      return success
    } catch (error) {
      console.error('发送通知失败:', error)
      return false
    }
  }

  /**
   * 发送订阅消息
   * @param notification 通知信息
   * @returns Promise<boolean>
   */
  private static async sendSubscriptionMessage(notification: Notification): Promise<boolean> {
    try {
      // 获取模板信息
      const template = this.TEMPLATES[notification.type]
      
      if (!template) {
        throw new Error(`未找到通知类型 ${notification.type} 的模板`)
      }
      
      // 获取用户信息
      const user = await CloudDataManager.getUserById(notification.userId)
      
      if (!user || !user.openid) {
        throw new Error('用户不存在或未绑定微信')
      }
      
      // 构建数据
      let data: any = {}
      
      // 如果是订单相关通知，获取订单信息
      if (notification.referenceId && ['order_created', 'order_confirmed', 'order_completed', 'order_cancelled', 'chef_assigned'].includes(notification.type)) {
        const order = await CloudDataManager.getData('orders', notification.referenceId) as Order
        
        if (order) {
          data = {
            character_string1: { value: order.id },
            phrase2: { value: this.getOrderStatusText(order.status) },
            time3: { value: formatDateTime(new Date()) },
            thing4: { value: order.items.map(item => item.dishName).join(', ').substring(0, 20) + (order.items.length > 2 ? '...' : '') },
            amount5: { value: order.finalAmount.toFixed(2) }
          }
        }
      }
      
      // 调用云函数发送订阅消息
      const result = await errorUtils.callCloudFunction('sendSubscription', {
        openid: user.openid,
        templateId: template.templateId,
        page: `${template.page}?id=${notification.referenceId || ''}`,
        data
      })
      
      return result && result.success === true
    } catch (error) {
      console.error('发送订阅消息失败:', error)
      return false
    }
  }

  /**
   * 标记通知为已读
   * @param notificationId 通知ID
   * @returns Promise<boolean>
   */
  static async markAsRead(notificationId: string): Promise<boolean> {
    try {
      await CloudDataManager.updateData('notifications', notificationId, {
        status: 'read',
        readAt: new Date()
      })
      
      return true
    } catch (error) {
      console.error('标记通知已读失败:', error)
      return false
    }
  }

  /**
   * 批量标记通知为已读
   * @param userId 用户ID
   * @returns Promise<boolean>
   */
  static async markAllAsRead(userId: string): Promise<boolean> {
    try {
      // 获取用户所有未读通知
      const notifications = await this.getUserNotifications(userId, false)
      
      // 批量更新
      for (const notification of notifications) {
        if (notification.id) {
          await this.markAsRead(notification.id)
        }
      }
      
      return true
    } catch (error) {
      console.error('批量标记通知已读失败:', error)
      return false
    }
  }

  /**
   * 获取用户通知
   * @param userId 用户ID
   * @param onlyUnread 是否只获取未读通知
   * @returns Promise<Notification[]>
   */
  static async getUserNotifications(userId: string, onlyUnread: boolean = false): Promise<Notification[]> {
    try {
      // 构建查询条件
      const query: any = { userId }
      
      if (onlyUnread) {
        query.status = { $ne: 'read' }
      }
      
      // 获取通知
      const notifications = await CloudDataManager.getAllData('notifications', query)
      
      // 按创建时间排序（最新的在前面）
      return notifications
        .map(notification => ({
          ...notification,
          createdAt: new Date(notification.createdAt),
          sentAt: notification.sentAt ? new Date(notification.sentAt) : undefined,
          readAt: notification.readAt ? new Date(notification.readAt) : undefined
        }))
        .sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime())
    } catch (error) {
      console.error('获取用户通知失败:', error)
      return []
    }
  }

  /**
   * 获取用户未读通知数量
   * @param userId 用户ID
   * @returns Promise<number>
   */
  static async getUnreadCount(userId: string): Promise<number> {
    try {
      const notifications = await this.getUserNotifications(userId, true)
      return notifications.length
    } catch (error) {
      console.error('获取未读通知数量失败:', error)
      return 0
    }
  }

  /**
   * 删除通知
   * @param notificationId 通知ID
   * @returns Promise<boolean>
   */
  static async deleteNotification(notificationId: string): Promise<boolean> {
    try {
      await CloudDataManager.deleteData('notifications', notificationId)
      return true
    } catch (error) {
      console.error('删除通知失败:', error)
      return false
    }
  }

  /**
   * 清理过期通知
   * @param days 保留天数
   * @returns Promise<number> 删除的通知数量
   */
  static async cleanupOldNotifications(days: number = 30): Promise<number> {
    try {
      // 计算截止日期
      const cutoffDate = new Date()
      cutoffDate.setDate(cutoffDate.getDate() - days)
      
      // 获取所有过期通知
      const oldNotifications = await CloudDataManager.getAllData('notifications', {
        createdAt: { $lt: cutoffDate }
      })
      
      // 批量删除
      let deletedCount = 0
      for (const notification of oldNotifications) {
        if (notification.id) {
          await CloudDataManager.deleteData('notifications', notification.id)
          deletedCount++
        }
      }
      
      return deletedCount
    } catch (error) {
      console.error('清理过期通知失败:', error)
      return 0
    }
  }

  /**
   * 创建订单状态变更通知
   * @param order 订单信息
   * @param type 通知类型
   * @returns Promise<string> 通知ID
   */
  static async createOrderStatusNotification(
    order: Order, 
    type: NotificationType
  ): Promise<string> {
    // 验证订单信息
    if (!order.userId) {
      throw new Error('订单缺少用户ID')
    }
    
    // 构建通知标题和内容
    let title = ''
    let content = ''
    
    switch (type) {
      case 'order_created':
        title = '订单已创建'
        content = `您的订单 ${order.id} 已成功创建，总金额 ${order.finalAmount.toFixed(2)} 元`
        break
        
      case 'order_confirmed':
        title = '订单已确认'
        content = `您的订单 ${order.id} 已确认，厨师 ${order.assignedChefName || '未知'} 正在准备中`
        break
        
      case 'order_completed':
        title = '订单已完成'
        content = `您的订单 ${order.id} 已完成，感谢您的使用`
        break
        
      case 'order_cancelled':
        title = '订单已取消'
        content = `您的订单 ${order.id} 已取消`
        break
        
      case 'chef_assigned':
        title = '厨师已分配'
        content = `您的订单 ${order.id} 已分配给厨师 ${order.assignedChefName || '未知'}`
        break
        
      default:
        title = '订单状态更新'
        content = `您的订单 ${order.id} 状态有更新`
    }
    
    // 创建通知
    const notification: Omit<Notification, 'id'> = {
      userId: order.userId,
      title,
      content,
      type,
      priority: NotificationPriority.NORMAL,
      status: 'pending',
      referenceId: order.id,
      createdAt: new Date(),
      data: {
        orderId: order.id,
        status: order.status,
        amount: order.finalAmount
      }
    }
    
    return await this.createNotification(notification)
  }

  /**
   * 处理未发送的通知
   * @returns Promise<number> 处理的通知数量
   */
  static async processFailedNotifications(): Promise<number> {
    try {
      // 获取所有失败或待发送的通知
      const pendingNotifications = await CloudDataManager.getAllData('notifications', {
        status: { $in: ['pending', 'failed'] }
      })
      
      let processedCount = 0
      
      // 逐个处理
      for (const notification of pendingNotifications) {
        if (notification.id) {
          const success = await this.sendNotification(notification.id)
          if (success) {
            processedCount++
          }
        }
      }
      
      return processedCount
    } catch (error) {
      console.error('处理未发送通知失败:', error)
      return 0
    }
  }

  /**
   * 获取订单状态文本
   * @param status 订单状态
   * @returns 状态文本
   */
  private static getOrderStatusText(status?: string): string {
    const statusMap: Record<string, string> = {
      pending: '待确认',
      confirmed: '已确认',
      completed: '已完成',
      cancelled: '已取消'
    }
    
    return status ? statusMap[status] || '未知' : '未知'
  }
}

// 导出工具函数
export const notificationUtils = {
  createNotification: NotificationUtils.createNotification,
  sendNotification: NotificationUtils.sendNotification,
  markAsRead: NotificationUtils.markAsRead,
  markAllAsRead: NotificationUtils.markAllAsRead,
  getUserNotifications: NotificationUtils.getUserNotifications,
  getUnreadCount: NotificationUtils.getUnreadCount,
  deleteNotification: NotificationUtils.deleteNotification,
  cleanupOldNotifications: NotificationUtils.cleanupOldNotifications,
  createOrderStatusNotification: NotificationUtils.createOrderStatusNotification,
  processFailedNotifications: NotificationUtils.processFailedNotifications
} 